/*
 * battery.cpp
 *
 *  Created on: 20 июн. 2024 г.
 *      Author: layst
 */

#include "battery.h"
#include "kl_libG070.h"
#include "MsgQ.h"

static uint32_t vbat_bad_value_cnt = 0;
static const uint32_t kbad_value_cnt_top = 7;
static const uint32_t kvoltage_charged_mv = 4005, kvoltage_discharged_mv = 3400;
static bool usb_was_connected = false;
static EvtId old_state = EvtId::None;

namespace battery {

void Init() {
    PinSetupInput(IS_CHARGING, pudPullUp);
    PinSetupInput(USB_DETECT, pudPullDown);
}

void OnMeasurement(uint32_t vbat) {
    Printf("VBat: %u\r", vbat);
    EvtId new_state = old_state;
    if(PinIsHi(USB_DETECT)) { // Check if USB connected
        usb_was_connected = true;
        if(PinIsLo(IS_CHARGING)) new_state = EvtId::BatteryIsCharging;
        else { // Pin is hi: slow charging or charging completed
            if(vbat > kvoltage_charged_mv) new_state = EvtId::BatteryChargingDone;
            else new_state = EvtId::BatteryIsCharging;
        }
    }
    else { // Usb not connected
        if(usb_was_connected) { // Disconnection occured
            usb_was_connected = false;
            new_state = EvtId::BatteryChargerDisconnected;
        }
        // Check if discharged
        if(vbat < kvoltage_discharged_mv) vbat_bad_value_cnt++;
        else vbat_bad_value_cnt = 0;
        if(vbat_bad_value_cnt > kbad_value_cnt_top) new_state = EvtId::BatteryDischarged;
    }
    // Send event if state changed
    if(new_state != old_state) {
        old_state = new_state;
        EvtQMain.SendNowOrExit(EvtMsg_t(new_state, vbat));
    }
}

} // namespace
